package com.tcxhb.job.core.schedule;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.tcxhb.job.common.Thread.NamedThreadFactory;
import com.tcxhb.job.common.constants.JobApiConstants;
import com.tcxhb.job.common.model.MiscResult;
import com.tcxhb.job.core.entity.ServerNode;
import com.tcxhb.job.core.service.job.AgentApiService;
import com.tcxhb.job.core.service.job.ServerMonitor;
import com.tcxhb.job.core.utils.UrlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @Auther: tcxhb
 * @Date: 2023/11/20
 */
@Component
@Slf4j
public class ServerMonitorScheduler implements DisposableBean, Scheduler {

    private ScheduledExecutorService monitorSchedule = Executors.newScheduledThreadPool(1,
            new NamedThreadFactory("server-monitor", true));
    // 间隔时间2分钟获取一次状态
    private Integer periodTime = 30;
    @Autowired
    private ServerMonitor serverMonitor;

    @Autowired
    private AgentApiService agentApiService;

    @Override
    @PostConstruct
    public void start() {
        monitorSchedule.scheduleAtFixedRate(() -> {
            try {
                  process();
            } catch (Exception e) {
                log.info("server-scan-error:", e);
            }
        }, 5, periodTime, TimeUnit.SECONDS);
    }

    /**
     *
     */
    public void process() {
        // 获取主机;
        String value = serverMonitor.runningServer();
        ServerNode node = serverMonitor.currentNode();
        if (node.getAddress().equals(value)) {
            return;
        }
        //判断是否在线
        Boolean result = checkServerOnline(value);
        if (Boolean.TRUE.equals(result)) {
            return;
        }
        // 不在线就释放
        serverMonitor.lock(value);
    }

    @Override
    public void destroy() throws Exception {
        serverMonitor.offline();
    }

    /**
     * 校验服务器状态
     *
     * @param value
     * @return
     */
    public boolean checkServerOnline(String value) {
        if (StringUtils.isBlank(value)) {
            return false;
        }
        //0 表示下线
        if ("0".equals(value)) {
            return false;
        }
        // ping 如果不在线,就抢占
        String[] ip = UrlUtils.splitHttp(value);
        for (int i = 0; i < 3; i++) {
            MiscResult<Boolean> result = agentApiService.beat(ip[0], Integer.parseInt(ip[1]), JobApiConstants.api_server_beat);
            if (result.isSuccess()) {
                return true;
            }
        }
        return false;
    }
}
